package com.solr.product.index;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.FacetField;
import org.apache.solr.client.solrj.response.FacetField.Count;
import org.apache.solr.client.solrj.response.Group;
import org.apache.solr.client.solrj.response.GroupCommand;
import org.apache.solr.client.solrj.response.GroupResponse;
import org.apache.solr.client.solrj.response.PivotField;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.GroupParams;
import org.apache.solr.common.util.NamedList;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSON;
import com.solr.product.bean.ProductIndex;
import com.solr.product.bean.SearchResult;
import com.solr.product.service.ProductService;
import com.solr.server.SolrCoudServer;
import com.solr.server.SolrServer;

public class ProductIndexHandler {

	@Autowired
	private ProductService productService;
	
	public void query() {
		
		HttpSolrClient client = SolrServer.getServer();
		/**
		 * 常用参数
		 * q - 查询字符串，必须的。  
		 * 	fl - 指定返回那些字段内容，用逗号或空格分隔多个。 
		 * start - 返回第一条记录在完整找到结果中的偏移位置，0开始。
		 * rows - 指定返回结果最多有多少条记录，配合start来实现分页。 
		 * 	sort - 排序，示例：(inStock desc, price asc)表示先 “inStock”降序, 再 “price”升序，默认是相关性降序。
		 * wt - (writer type)指定输出格式，可以有 xml, json, php, phps。 
		 * fq - (filter query )过虑查询，作用：在q查询符合结果中同时是fq查询符合的，
		 * 例如：q=mm&fq=date_time:[20081001 TO 20091031]，找关键字mm，并且date_time是20081001到20091031之间的
		 * 
		 * 不常用的参数
		 * 
		 * q.op - 覆盖schema.xml的defaultOperator（有空格时用“AND”还是用“OR”操作逻辑），
		 * 一般默认指定  “OR”df - 默认的查询字段，一般默认指定  
		 * qt – (query type)指定那个类型来处理查询请求，一般不用指定，默认是standard。
		 * indent - 返回的结果是否缩进，默认关闭，用 indent=true|on 开启，一般调试json,php,phps,ruby输出才有必要用这个参数。  
		 * version - 查询语法的版本，建议不使用它，由服务器指定默认值。
		 * 
		 * 操作符
		 * “:”指定字段查指定值，如返回所有值*:*
		 * “?”表示单个任意字符的通配 
		 * “*” 表示多个任意字符的通配（不能在检索的项开始使用*或者?符号）
		 * “~”表示模糊检索，如检索拼写类似于”roam”的项这样写：roam~将找到形如foam和roams的单词；roam~0.8，检索返回相似度在0.8以上的记录。
		 *  邻近检索，如检索相隔10个单词的“apache”和”“akarta”，“jakarta apache”~10 
		 * “^”控制相关度检索，如检索jakarta apache，同时希望去让“jakarta”的相关度更加好，那么在其后加上”^”符号和增量值，即jakarta^4 apache
		 * 布尔操作符AND、||
		 * 布尔操作符OR、&& 
		 * 布尔操作符NOT、!、-（排除操作符不能单独与项使用构成查询） 
		 * “+” 存在操作符，要求符号“+”后的项必须在文档相应的域中存在
		 *  ( ) 用于构成子查询
		 *  [ ] 包含范围检索，如检索某时间段记录，包含头尾，date:[200707 TO 200710] 
		 *  { }不包含范围检索，如检索某时间段记录，不包含头尾 
		 *  date:{200707 TO 200710} 
		 *  " 转义操作符，特殊字符包括+ - && || ! ( ) { } [ ] ^ ” ~ * ? : " 

		 */		
		SolrQuery query = new SolrQuery();
		//*********************基本查询开始********************************
		query.set("q", "*:*");
		query.setStart(0);//分页
		query.setRows(10);//分页
		query.set("fl", "id,name");//指定返回结果
		//query.set("wt", "json");//数据返回格式
		//query.setQuery(" +name:抽纸");//查询条件
		//query.setFilterQueries("");
		//BoolQueryBuilder
		
		query.setFilterQueries(" -id:1466 +price:[2000 TO 3000]");//过滤查询
		
		//*********************基本查询结束********************************
		
		try {
			System.out.println("查询条件："+query.toQueryString());
			QueryResponse response = client.query(query, SolrRequest.METHOD.POST);
						
			SolrDocumentList docs = response.getResults();
			response.getResults();
			List<SearchResult> list = response.getBeans(SearchResult.class);
			System.out.println("命中："+docs.getNumFound()+"条");
			/*for (SolrDocument doc : docs) {
				System.out.println(doc.get("id")+"\t "+doc.getFieldValue("name"));
				
			}*/
			
			for (SearchResult searchResult : list) {
				System.out.println(searchResult.getId()+"\t"+searchResult.getName());
			}
			
			
			
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
	}
	
	public void facet() throws SolrServerException, IOException {
		SolrQuery query = new SolrQuery();
		query.setQuery("*:*");
		query.setRows(0);
		// *********************facet查询开始********************************
		query.setFacet(true);// 设置facet=on，打开facet
		query.addFacetField(new String[] { "storeid", "column" });// 设置需要facet的字段
		query.setFacetLimit(1000);// -1 现在facet返回的数量
		query.setFacetMissing(false);// 不统计null的值
		query.setFacetMinCount(1);// 设置返回的数据中每个分组的数据最小值，比如设置为1，则统计数量最小为1，小于1的不显示
		query.addFacetQuery("price:[10 TO 30]");
		query.setFilterQueries(" -id:1466 +price:[2000 TO 3000]");//过滤查询

		// *********************facet查询结束********************************
		System.out.println(query.toQueryString());
		HttpSolrClient client = SolrServer.getServer();
		QueryResponse response = client.query(query, SolrRequest.METHOD.POST);
		List<FacetField> facetFields = response.getFacetFields();
		for (FacetField field : facetFields) {
			System.out.println(field.getName()+":"+field.getValueCount());
			//System.out.println(field.getValueCount());
			List<Count> values = field.getValues();
			for (Count count : values) {
				System.out.println(count.getName()+":"+count.getCount());
			}
			System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
			
		}
	}
	
	
	public void facetPivot(){
		HttpSolrClient server = SolrServer.getServer();
		SolrQuery query = new SolrQuery();
		query.setQuery("*:*");
		query.setRows(0);
		query.setFacet(true);
		query.addFacetPivotField(new String[] { "storeid", "column" });
		//query.add("facet.pivot","storeid,column");
		query.setFacetLimit(1000);
		try {
			QueryResponse response = server.query(query,	SolrRequest.METHOD.POST);
			NamedList<List<PivotField>> facetPivot = response.getFacetPivot();
			System.out.println(facetPivot);
			List<PivotField> pivotFieldList = null;
			for (int i = 0; i < facetPivot.size(); i++) {
				pivotFieldList = facetPivot.getVal(i);
				print(pivotFieldList,1);
			}
			
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void print(List<PivotField> pivotFieldList, int index){
		if (pivotFieldList == null || pivotFieldList.isEmpty()) {
			return;
		}
		for (PivotField pivotField : pivotFieldList) {
			System.out.println();
			System.out.println(index+"级："+pivotField.getValue()+"     "+pivotField.getCount());
			print(pivotField.getPivot(), index++);
		}
	}
	
	public void createIndex(int start, int limit){
		HttpSolrClient client = SolrServer.getServer();
		try {
			List<ProductIndex> productIndexs = productService.getIndex(start, limit);
			if (productIndexs == null || productIndexs.isEmpty()) {
				System.out.println("没有所以需要创建");
				return;
			}
			List<SolrInputDocument> docs = new ArrayList<SolrInputDocument>(productIndexs.size());
			for (ProductIndex productIndex : productIndexs) {
				SolrInputDocument doc = new SolrInputDocument();
				doc.addField("id", productIndex.getProductid());
				doc.addField("name", productIndex.getName());
				doc.addField("pingyinname", productIndex.getPingyinname());
				doc.addField("price", productIndex.getPriceValue());
				doc.addField("storeid", productIndex.getStoreid());
				doc.addField("column", productIndex.getColumn());
				docs.add(doc);
			}
			client.add(docs);
			client.commit();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		
	}
	
	public void group(){
		HttpSolrClient server = SolrServer.getServer();
		SolrQuery query = new SolrQuery();
		query.setQuery("*:*");
		//设置通过group查询为true，表示查询时使用group机制
		query.setParam(GroupParams.GROUP, true);
		//设置group查询的域
		query.setParam(GroupParams.GROUP_FIELD, "storeid");
		//query.setParam(GroupParams.GROUP_FIELD, "column");

		//设置每组最多返回的记录数，可用于数据采集，若只需要数量，可设置为0
		query.setParam(GroupParams.GROUP_LIMIT, "5");
		//设置返回的行数
		query.setRows(10);
		
		try {
			System.out.println(query.toQueryString());
			QueryResponse response = server.query(query, SolrRequest.METHOD.POST);
			if (response != null) {
				GroupResponse groupResponse = response.getGroupResponse();
				List<GroupCommand> values = groupResponse.getValues();
				for (GroupCommand command : values) {
					String name = command.getName();
					System.out.println("name="+name);
					List<Group> groups = command.getValues();
					for (Group group : groups) {
						System.out.println("组"+group.getGroupValue());
						SolrDocumentList result = group.getResult();
						for (int i = 0; i < result.size(); i++) {
							SolrDocument doc = result.get(i);
							System.out.println(JSON.toJSON(doc).toString());
						}
						System.out.println("************************************");
						/*
						System.out.println(group.getResult().get(0).getFieldValue("storeid")+"  "
								+group.getResult().get(1).getFieldValue("storeid"));
						System.out.println("group查询..."+group.getGroupValue()+" 数量为："+group.getResult().getNumFound()+"  "
								+group.getResult().get(0).getFieldValue("column"));
					*/
					}
				}
			}
		} catch (SolrServerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	public void createCouldIndex(int start, int limit){
		CloudSolrClient client = SolrCoudServer.getInstance().getServer();
		try {
			List<ProductIndex> productIndexs = productService.getIndex(start, limit);
			if (productIndexs == null || productIndexs.isEmpty()) {
				System.out.println("没有所以需要创建");
				return;
			}
			List<SolrInputDocument> docs = new ArrayList<SolrInputDocument>(productIndexs.size());
			for (ProductIndex productIndex : productIndexs) {
				SolrInputDocument doc = new SolrInputDocument();
				doc.addField("id", productIndex.getProductid());
				doc.addField("name", productIndex.getName());
				doc.addField("pingyinname", productIndex.getPingyinname());
				doc.addField("price", productIndex.getPriceValue());
				doc.addField("storeid", productIndex.getStoreid());
				doc.addField("column", productIndex.getColumn());
				docs.add(doc);
			}
			client.add(docs);
			client.commit();
			System.out.println("创建成功");
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
